﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Windows.Forms;
using System.Drawing;
using System.Threading;
using System.Timers;

namespace CIRDiagnoseDevice.Test
{
    class _450MDispatchCommTrial
    {
        #   region 全局变量
        private CommunicationWithInterfaceUnit Unit = new CommunicationWithInterfaceUnit();
        private InitSerialPort InitPort = new InitSerialPort();
        private byte[] RBuffer = new byte[500]; // 接收测试仪返回结果
        private List<byte> ListBuffer = new List<byte>();//缓存接收数据
        private int Index;
        private LBJAndTrainEndTest Lbj = new LBJAndTrainEndTest();
        private SerialPort OSP;
        private byte validated, received;
        private DataGridView dgv;
        private int StartIndex;
        public event MessageNotice OnMessageNotice;
        private Thread dispatchThread;
        private System.Timers.Timer timer = new System.Timers.Timer();
        private GSM_RFunTrial Gsm_RFunTrial;
        private string ToolStripInfo;
        #   endregion
        public _450MDispatchCommTrial(DataGridView dgv, int startIndex, GSM_RFunTrial Gsm_RFunTrial)
        {
            this.dgv = dgv;
            this.StartIndex = startIndex;
            this.Gsm_RFunTrial = Gsm_RFunTrial;
        }

        public void Start450MDispatch(ref Thread thread)
        {
            if (MessageBox.Show("现在进行450M调度命令功能试验，请选择频率为458.2MHZ运行线路 ,\r\n\r\n 并将CIR连接到450M列尾试验单元且将MMI扬声器改为内置！", "用户操作提示", MessageBoxButtons.OK) == DialogResult.OK)
            {
                SendDispatchCommand(OSP);
            }

            thread = new Thread(new ThreadStart(DealWithData));
            thread.IsBackground = true;
            thread.Start();
            timer.Enabled = true;
            ToolStripInfo = "正在试验450M调度命令功能";
            MainFrm.MotherFrm.SetToolStrip(ToolStripInfo);
        }

        public void InitParameter(SerialPort OSP)
        {
            this.OSP = OSP;
            InitPort.Open(this.OSP);
            this.OSP.ReadTimeout = 45000;
            this.OSP.DataReceived += new SerialDataReceivedEventHandler(OSP_DataReceived);
            validated = 0x00;
            received = 0x00;
            dgv.Rows[StartIndex].Cells["试验结果"].Value = "";
            ListBuffer.Clear();
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            timer.Interval = 20000;
        }

        public void ClearSource()
        {
            GC.Collect();
        }

        void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            //this.OSP.ReadTimeout = 45000;
            //this.OSP.DataReceived += new SerialDataReceivedEventHandler(OSP_DataReceived);
            SendDispatchCommand(OSP);
            timer.Enabled = false;
        }

        void OSP_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            while (!MainFrm.MotherFrm.StopTest)
            {
                while (!MainFrm.MotherFrm.Suspend)
                {
                    int readNum = 0;
                    if (MainFrm.MotherFrm._450MDispatchFunTrial)
                    {
                        try
                        {
                            try
                            {
                                //readNum = OSP3.BytesToRead;
                                readNum = OSP.Read(RBuffer, 0, 200);
                            }
                            catch (Exception ex)
                            {
                                if (ex.GetType() == typeof(TimeoutException))
                                {
                                    if (MainFrm.MotherFrm._450MDispatchFunTrial)
                                    {
                                        FillGridWithJudgeResult(dgv, StartIndex + 0, "不合格", false);
                                        MainFrm.MotherFrm.ChangeButtonText();
                                        MainFrm.MotherFrm._450MDispatchFunTrial = false;
                                        MainFrm.MotherFrm._450MDispatchTrialSaved = false;
                                        MainFrm.MotherFrm.StopTest = true;
                                        MainFrm.MotherFrm.Suspend = true;
                                        if (MainFrm.MotherFrm.IsTestTotal)
                                        {
                                            MainFrm.MotherFrm.WholeFunTrialSaved = false;
                                            MainFrm.MotherFrm.TestTotalSaved = false;
                                        }
                                        OSP.Close();
                                        OSP.DataReceived -= new SerialDataReceivedEventHandler(OSP_DataReceived);
                                        timer.Enabled = false;
                                        if (MainFrm.MotherFrm.IsTestTotal == false)
                                        {
                                            MainFrm.MotherFrm.ChangeButtonText();
                                        }
                                        ToolStripInfo = "450M调度命令功能试验完成";
                                        MainFrm.MotherFrm.SetToolStrip(ToolStripInfo);
                                        MessageBox.Show("450M调度命令试验完成！");
                                        if (OnMessageNotice != null)
                                        {
                                            OnMessageNotice(this, ThreadRunState.End);
                                        }
                                    }
                                }
                            }
                            byte[] temp = new byte[readNum];
                            Array.Copy(RBuffer, 0, temp, 0, readNum);
                            lock (this)
                            {
                                ListBuffer.AddRange(temp);
                            }
                        }
                        catch
                        {

                        }
                    }
                }
            }
        }

        private void DealWithData()
        {
            while (!MainFrm.MotherFrm.StopTest)
            {
                while (!MainFrm.MotherFrm.Suspend)
                {
                    if (MainFrm.MotherFrm._450MDispatchFunTrial)
                    {
                        try
                        {
                            if (ListBuffer.Count > 16)
                            {
                                int startIndex = 0;
                                startIndex = FindDataFrameHead(ListBuffer, (byte)0x10, (byte)0x02, 0, ListBuffer.Count, true);
                                if (startIndex < 0)
                                    continue;
                                int endIndex = FindDataFrameHead(ListBuffer, (byte)0x10, (byte)0x03, startIndex, ListBuffer.Count, false);
                                if (endIndex < 0)
                                    continue;
                                int length = endIndex - startIndex + 2;
                                byte[] readData = new byte[length];
                                ListBuffer.CopyTo(startIndex, readData, 0, length);
                                ListBuffer.RemoveRange(0, endIndex + 2);
                                Index = 0;
                                byte[] realData = Lbj.DePacketData(readData);
                                if (realData.Length < 14)
                                    continue;
                                if (readData[10] == 0x81)
                                {
                                    validated = 0x81;
                                    timer.Enabled = false;
                                    continue;
                                }
                                else if (readData[10] == 0x82)
                                {
                                    received = 0x82;
                                }
                                if (validated == 0x81 && received == 0x82)
                                {
                                    FillGridWithJudgeResult(dgv, StartIndex, "合格", true);
                                    MainFrm.MotherFrm._450MDispatchFunTrial = false;
                                    MainFrm.MotherFrm._450MDispatchTrialSaved = false;

                                  
                                    MessageBox.Show("450M调度命令试验完成！");
                                    if (MainFrm.MotherFrm.IsTestTotal == false)
                                    {
                                        MainFrm.MotherFrm.StopTest = true;
                                        MainFrm.MotherFrm.Suspend = true;
                                        MainFrm.MotherFrm.ChangeButtonText();
                                        OSP.Close();
                                        OSP.DataReceived -= new SerialDataReceivedEventHandler(OSP_DataReceived);
                                    }
                                    if (OnMessageNotice != null)
                                    {
                                        OnMessageNotice(this, ThreadRunState.End);
                                        MainFrm.MotherFrm.StopTest = true;
                                        MainFrm.MotherFrm.Suspend = true;
                                        OSP.Close();
                                        OSP.DataReceived -= new SerialDataReceivedEventHandler(OSP_DataReceived);
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {

                        }
                    }
                }
            }
        }

        //查找帧头和帧尾
        private int FindDataFrameHead(List<byte> arr, byte head1, byte head2, int startIndex, int findLength, bool isFindHead)
        {
            int index = -1;
            int length = 0;
            length = findLength > arr.Count ? arr.Count : findLength;
            for (int i = startIndex; i < length - 1; i++)
            {
                if (arr[i] == head1 && arr[i + 1] == head2)
                {
                    index = i;
                    break;
                }
            }

            return index;
        }

        public void SendDispatchCommand(SerialPort OSP)
        {
            List<byte> data = new List<byte>();
            data.Add(0x00);
            data.Add(0x32);
            data.Add(0x30);
            data.Add(0x37);
            data.Add(0x39);
            data.Add(0x00);
            data.Add(0x20);
            data.Add(0x88);
            byte[] dispatchInfo = DispatchCommand();
            byte length = (byte)dispatchInfo.Length;
            data.Add(length);
            for (int i = 0; i < dispatchInfo.Length; i++)
            {
                data.Add(dispatchInfo[i]);
            }
            byte[] frameData = data.ToArray();

            short len = (short)(frameData.Length + 2); // 长度包含CRC长度在内
            data.Clear();

            data.Add(0x02);  //源端口
            data.Add(0x00);  // 源地址长度
            data.Add(0x05); // 目的端口
            data.Add(0x00); // 目的地址长度
            data.Add(0x06); // 业务类型 0X06为调度命令
            data.Add(0x01); // 命令字
            data.Add(0x0c);  // 调度命令模式字
            //short len = (short)dataB.Length;
            data.Add((byte)len); //数据长度
            //data.Add((byte)(len >> 8)); // 数据长度高字节
            for (int i = 0; i < frameData.Length; i++)
            {
                data.Add(frameData[i]);
            }
            frameData = data.ToArray();
            byte[] sendData = Unit.PacketData(frameData);
            if (OSP.IsOpen)
            {
                OSP.Write(sendData, 0, sendData.Length);
            }
            MessageBoxTimeOut message = new MessageBoxTimeOut();
            message.Show("请在收到调度命令后30秒内签收！", "提示", 3500);
        }

        private byte[] DispatchCommand()
        {
            try
            {
                List<byte> data = new List<byte>();
                byte year = (byte)(System.DateTime.Now.Year % 20);
                byte month = (byte)(System.DateTime.Now.Month);
                byte day = (byte)(System.DateTime.Now.Day);
                string content = "调度命令测试";
                byte[] contentByte = System.Text.ASCIIEncoding.Default.GetBytes(content);
                data.Add(0x01);// 功能码
                data.Add((byte)HexToBCD(year, 2));
                data.Add((byte)HexToBCD(month, 2));
                data.Add((byte)HexToBCD(day, 2));
                byte hour = (byte)HexToBCD((ulong)System.DateTime.Now.Hour, 2);
                byte minute = (byte)HexToBCD((ulong)System.DateTime.Now.Minute, 2);
                byte second = (byte)HexToBCD((ulong)System.DateTime.Now.Second, 2);
                data.Add(hour);
                data.Add(minute);
                data.Add(second);
                data.Add(hour);
                data.Add(minute);
                data.Add(second);
                for (int i = 0; i < 7; i++) // 7位车次号
                {
                    data.Add(0x58);
                }

                string cabNo = string.Empty;
                if (MainFrm.MotherFrm.CabNum1 == 0 && MainFrm.MotherFrm.CabNum2 == 0 && MainFrm.MotherFrm.CabNum3 == 0 && MainFrm.MotherFrm.CabNum4 == 0)
                {
                    CabNO cn = new CabNO();
                    cn.ShowDialog();
                    cabNo = cn.CabStr;

                    byte[] cabByte = System.Text.ASCIIEncoding.Default.GetBytes(cabNo);//(GPRS_CabNum);
                    int len2 = cabByte.Length;
                    MainFrm.MotherFrm.CabNum1 = (byte)((byte)((cabByte[0] - 0x30) << 4) + (cabByte[1] - 0x30));
                    MainFrm.MotherFrm.CabNum2 = (byte)((byte)(cabByte[2] - 0x30) << 4);
                    int j = 0;
                    for (int i = 0; i < 3; i++)
                    {
                        data.Add(cabByte[i]); // 机车类型代码3位 ASCII码
                    }
                    for (int i = 4; i >= 0; i--)
                    {
                        if (i >= len2 - 3)
                        {
                            data.Add(0x30);  //机车编号5位，不足5位高位填0补齐 ASCII码
                            j++;
                        }
                        else
                        {
                            data.Add(cabByte[len2 - i - 1]);
                        }
                    }
                    if (j == 0)
                    {
                        MainFrm.MotherFrm.CabNum2 += (byte)(cabByte[3] - 0x30);
                        MainFrm.MotherFrm.CabNum3 = (byte)((byte)((cabByte[4] - 0x30) << 4) + (cabByte[5] - 0x30));
                        MainFrm.MotherFrm.CabNum4 = (byte)((byte)((cabByte[6] - 0x30) << 4) + (cabByte[7] - 0x30));
                    }
                    else if (j == 1)
                    {
                        MainFrm.MotherFrm.CabNum3 = (byte)((byte)((cabByte[4] - 0x30) << 4) + (cabByte[5] - 0x30));
                        MainFrm.MotherFrm.CabNum4 = (byte)((byte)((cabByte[6] - 0x30) << 4) + (cabByte[7] - 0x30));
                    }
                    else if (j == 2)
                    {
                        MainFrm.MotherFrm.CabNum3 = (byte)(cabByte[5] - 0x30);
                        MainFrm.MotherFrm.CabNum4 = (byte)((byte)((cabByte[6] - 0x30) << 4) + (cabByte[7] - 0x30));
                    }
                    else if (j == 3)
                    {
                        MainFrm.MotherFrm.CabNum4 = (byte)((byte)((cabByte[6] - 0x30) << 4) + (cabByte[7] - 0x30));
                    }
                    else if (j == 4)
                    {
                        MainFrm.MotherFrm.CabNum4 = (byte)(cabByte[7] - 0x30);

                    }
                }
                else
                {
                    data.Add((byte)((MainFrm.MotherFrm.CabNum1 >> 4) + 0x30));
                    data.Add((byte)((MainFrm.MotherFrm.CabNum1 & 0x0f) + 0x30));
                    data.Add((byte)((MainFrm.MotherFrm.CabNum2 >> 4) + 0x30));
                    data.Add((byte)((MainFrm.MotherFrm.CabNum2 & 0x0f) + 0x30));
                    data.Add((byte)((MainFrm.MotherFrm.CabNum3 >> 4) + 0x30));
                    data.Add((byte)((MainFrm.MotherFrm.CabNum3 & 0x0f) + 0x30));
                    data.Add((byte)((MainFrm.MotherFrm.CabNum4 >> 4) + 0x30));
                    data.Add((byte)((MainFrm.MotherFrm.CabNum4 & 0x0f) + 0x30));
                }
                data.Add(0x01);
                data.Add(0x31);
                data.Add(0x31);
                data.Add(0x32);
                for (int i = 0; i < 11; i++)
                {
                    data.Add(0x20);
                }
                for (int i = 0; i < 6; i++)
                {
                    data.Add(0x00);
                }
                data.Add(0x01);
                data.Add(0x01);
                data.Add(0xC1);
                data.Add(0xD0);
                data.Add(0xB3);
                data.Add(0xB5);
                data.Add(0xBD);
                data.Add(0xF8);
                data.Add(0xC2);
                data.Add(0xB7);
                data.Add(0xD4);
                data.Add(0xA4);
                data.Add(0xB8);
                data.Add(0xE6);
                data.Add(0x0D);
                data.Add(0x0A);
                data.Add(0xCF);
                data.Add(0xC2);
                data.Add(0xD7);
                data.Add(0xAF);
                data.Add(0xD5);
                data.Add(0xBE);
                data.Add(0x0D);
                data.Add(0x0A);
                for (int i = 0; i < contentByte.Length; i++)
                {
                    data.Add(contentByte[i]);
                }
                byte[] frameData = data.ToArray();
                return frameData;
            }
            catch (System.Exception ex)
            {
                return null;
            }
        }

        public ulong HexToBCD(ulong phex, uint num)//HEX码转换成BCD码
        {
            int i;
            ulong pdiv, pmul;

            byte[] tmp = new byte[num];
            pdiv = phex;
            for (i = 0; i < num; i++)
            {
                tmp[i] = (byte)(pdiv % 10);
                pdiv = pdiv / 10;
            }
            pmul = 1;
            pdiv = 0;
            for (i = 0; i < num; i++)
            {
                pdiv = pdiv + pmul * tmp[i];
                pmul = pmul * 0x10;
            }
            return pdiv;
        }

        //将测试判断结果填写到测试表中
        private void FillGridWithJudgeResult(DataGridView gridview, int rowIndex, string result, bool isGreen)
        {
            if (gridview.InvokeRequired)
            {
                gridview.Invoke(new MethodInvoker(delegate
                {
                    gridview.Rows[rowIndex].Cells["试验结果"].Value = result;
                    if (isGreen)
                        gridview.Rows[rowIndex].Cells["试验结果"].Style.ForeColor = Color.Green;
                    else
                        gridview.Rows[rowIndex].Cells["试验结果"].Style.ForeColor = Color.Red;
                    gridview.Refresh();
                }));
            }
            else
            {
                gridview.Rows[rowIndex].Cells["试验结果"].Value = result;
                if (isGreen)
                    gridview.Rows[rowIndex].Cells["试验结果"].Style.ForeColor = Color.Green;
                else
                    gridview.Rows[rowIndex].Cells["试验结果"].Style.ForeColor = Color.Red;
                gridview.Refresh();
            }
        }
    }
}
